﻿using Microsoft.Extensions.DependencyInjection;
using RotovapPlatform.Domain.Equipment.Interfaces.Communication;
using RotovapPlatform.Infrastructure.Equipment.Communication.Modbus;
using RotovapPlatform.Infrastructure.Equipment.Communication.SerialServer;
using RotovapPlatform.Infrastructure.Equipment.Devices.Robot;
using RotovapPlatform.Domain.Equipment.Configurations;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RotovapPlatform.Domain.Equipment.Device.Motors;
using RotovapPlatform.Domain.Equipment.Interfaces.Base;
using RotovapPlatform.Domain.Equipment.Interfaces.Robot;
using RotovapPlatform.Infrastructure.Equipment.Devices.TCU;
using RotovapPlatform.Infrastructure.Equipment.Communication.Ethercat;
using Microsoft.Extensions.Configuration;
using RotovapPlatform.Infrastructure.Equipment.Devices.EtherCATMotor;
using RotovapPlatform.Domain.Business.Interfaces;
using RotovapPlatform.Infrastructure.Business.Recipes;
using RotovapPlatform.Infrastructure.Business.ExperimentGroups;
using RotovapPlatform.Infrastructure.Business.Storage;
using RotovapPlatform.Infrastructure.Business.Experiments;
using RotovapPlatform.Domain.Equipment.Interfaces.Services;
using RotovapPlatform.Infrastructure.Services;
using System.IO;
using System.Reflection;
using RotovapPlatform.Domain.Equipment.DeviceParameters;
using System.Threading.Tasks;
using System.Text.Json;
using RotovapPlatform.Infrastructure.Equipment.Devices.OilBath;
using RotovapPlatform.Infrastructure.Equipment.Devices.IO;
using RotovapPlatform.Infrastructure.Equipment.Devices.TemperatureCollector;
using RotovapPlatform.Infrastructure.Equipment.Devices.Valve;
namespace RotovapPlatform.Infrastructure.DependencyInjection
{
	public static class InfrastructureModule
	{
		public static IServiceCollection AddInfrastructureServices(this IServiceCollection services)
		{
			// 确保配置目录存在
			var baseDir = AppDomain.CurrentDomain.BaseDirectory;
			var configDir = Path.Combine(baseDir, "Config");
			if (!Directory.Exists(configDir))
			{
				Directory.CreateDirectory(configDir);
			}

			// 获取Infrastructure层的默认配置文件路径

			var assemblyLocation = Assembly.GetExecutingAssembly().Location;
			var assemblyDir = Path.GetDirectoryName(assemblyLocation);
			var infrastructureDir = Path.GetDirectoryName(assemblyDir); // 上一级目录
			var defaultConfigSourcePath = Path.Combine(infrastructureDir, "Config", "defaultDeviceParameters.json");

			// 如果Infrastructure层的默认配置文件不存在，尝试从项目目录获取
			if (!File.Exists(defaultConfigSourcePath))
			{
				var solutionDir = Path.GetFullPath(Path.Combine(baseDir, "..\\..\\..\\..\\.."));
				defaultConfigSourcePath = Path.Combine(solutionDir, "src", "RotovapPlatform.Infrastructure", "Config", "defaultDeviceParameters.json");
			}

			// 目标配置文件路径
			var configFilePath = Path.Combine(configDir, "deviceParameters.json");
			var defaultConfigFilePath = Path.Combine(configDir, "defaultDeviceParameters.json");


			// 如果默认配置文件不存在，但源文件存在，则复制
			if (!File.Exists(defaultConfigFilePath) && File.Exists(defaultConfigSourcePath))
			{
				try
				{
					File.Copy(defaultConfigSourcePath, defaultConfigFilePath, true);
				}
				catch (Exception ex)
				{
					// 记录错误但继续执行
					Console.WriteLine($"复制默认配置文件失败: {ex.Message}");
				}
			}

			// 注册设备参数服务
			services.AddSingleton<IDeviceParameterService, DeviceParameterService>(provider =>
			{
				var logger = provider.GetRequiredService<Microsoft.Extensions.Logging.ILogger<DeviceParameterService>>();
				return new DeviceParameterService(logger, configFilePath, defaultConfigFilePath);
			});

			// 注册仓储
			services.AddScoped<IRecipeRepository, RecipeRepository>();
			services.AddScoped<IStorageLocationRepository, StorageLocationRepository>();
			services.AddScoped<IExperimentGroupRepository, ExperimentGroupRepository>();
			services.AddScoped<IExperimentRepository, ExperimentRepository>();

			//// 配置Modbus TCP
			//services.Configure<ModbusTcpConfig>(options =>
			//{
			//	options.IpAddress = "192.168.1.250";
			//	options.Port = 6502;
			//});

			// 配置Modbus TCP
			services.Configure<ModbusTcpConfig>(options =>
			{
				options.IpAddress = "192.168.1.111";
				options.Port = 502;
			});

			// 配置机器人
			services.Configure<RobotConfig>(options =>
			{
				options.SlaveId = 1;
				options.DeviceStatusStartAddress = 8;
				options.TaskFeedbackStartAddress = 96;
				options.ControlCommandStartAddress = 40;
				options.TaskSendStartAddress = 100;
				options.ContinueExecutionSignalAddress = 107;
				options.TaskStartAddress = 110;
			});

			// 配置串口服务器
			services.Configure<SerialServerConfig>(options =>
			{
				options.IpAddress = "192.168.1.12";
				options.DevicePorts = new List<int>
				{
					502,   // TCU端口
					503,   // 油浴锅端口
					504,   // 温度采集模块端口
					505,   // 扫码器端口
				};
			});

			// 注册配置服务
			services.AddSingleton(sp => sp.GetRequiredService<IOptions<ModbusTcpConfig>>().Value);
			services.AddSingleton(sp => sp.GetRequiredService<IOptions<RobotConfig>>().Value);
			services.AddSingleton(sp => sp.GetRequiredService<IOptions<SerialServerConfig>>().Value);

			// 注册通信服务
			services.AddSingleton<IModbusTcpClient, ModbusTcpClient>();
			services.AddSingleton<ISerialServerManager, SerialServerManager>();
			services.AddSingleton<IEtherCATManager, EtherCATManager>();
			services.AddSingleton<IIOModuleService, IOModuleService>();

			// 注册机器人服务
			services.AddSingleton<IRobotEM>(sp =>
			{
				var modbus = sp.GetRequiredService<IModbusTcpClient>();
				var config = sp.GetRequiredService<RobotConfig>();
				var logger = sp.GetRequiredService<ILogger<RobotDrive>>();
				return new RobotDrive(modbus, config, logger);
			});

			//// 注册TCU配置对象
			//services.Configure<SerialDeviceConfig>(options =>
			//{
			//	options.TCUs.AddRange(new[]
			//	{
			//		new TCUConfig { Port = 502, SlaveId = 1, Name = "MainTCU" },
			//	});
			//});

			//注册油浴锅配置对象
			services.Configure<SerialDeviceConfig>(options =>
			{
				options.OilBaths.AddRange(new[]
				{
					new OilBathConfig { Port = 503, SlaveId = 1, Name = "MainOilBath" },
				});
			});

			//注册温度采集模块配置对象
			services.Configure<SerialDeviceConfig>(options =>
			{
				options.TemperatureCollectors.AddRange(new[]
				{
					new TemperatureCollectorConfig { Port = 504, SlaveId = 1, Name = "MainTemperatureCollector" },
				});
			});

			// 注册切换阀配置 - 使用COM口直连方式
			services.Configure<ValveConfig>(options =>
			{
				options.SwitchValves.AddRange(new[]
				{
					new ValveDeviceConfig
					{
						PortName = "COM8",
						SlaveId = 0,
						Name = "MainSwitchValve"
					}
				});
			});

			// 获取配置实例
			var serviceProvider = services.BuildServiceProvider();
			var config = serviceProvider.GetRequiredService<IOptions<SerialDeviceConfig>>().Value;

			// 注册TCU驱动
			foreach (var tcuConfig in config.TCUs)
			{
				services.AddSingleton<ITCUBase>(sp =>
					new TCUDrive(
						sp.GetRequiredService<ISerialServerManager>(),
						tcuConfig.Port,
						tcuConfig.SlaveId,
						tcuConfig.Name,
						sp.GetRequiredService<ILogger<TCUDrive>>()
					)
				);
			}

			//注册油浴锅驱动
			foreach (var oilBathConfig in config.OilBaths)
			{
				services.AddSingleton<IOilBathBase>(sp =>
					new OilBathDrive(sp.GetRequiredService<ISerialServerManager>(),
					oilBathConfig.Port,
					oilBathConfig.SlaveId,
					oilBathConfig.Name,
					sp.GetRequiredService<ILogger<OilBathDrive>>()));
			}

			//注册温度采集模块驱动
			foreach (var temperatureCollectorConfig in config.TemperatureCollectors)
			{
				services.AddSingleton<ITemperatureCollectorBase>(sp =>
					new TemperatureCollectorDrive(sp.GetRequiredService<ISerialServerManager>(),
					temperatureCollectorConfig.Port,
					temperatureCollectorConfig.SlaveId,
					temperatureCollectorConfig.Name,
					sp.GetRequiredService<ILogger<TemperatureCollectorDrive>>()));
			}

			// 注册切换阀驱动 - 串口直连方式
			var valveServiceProvider = services.BuildServiceProvider();
			var directValveConfig = valveServiceProvider.GetRequiredService<IOptions<RotovapPlatform.Domain.Equipment.Configurations.ValveConfig>>().Value;

			foreach (var valveDeviceConfig in directValveConfig.SwitchValves)
			{
				services.AddSingleton<IValveBase>(sp =>
					new ValveDrive(
						valveDeviceConfig.PortName,
						valveDeviceConfig.SlaveId,
						valveDeviceConfig.Name,
						sp.GetRequiredService<ILogger<ValveDrive>>()
					));
			}

			Console.WriteLine("==========================================================");
			Console.WriteLine("InfrastructureModule: 准备注册电机");
			Console.WriteLine("==========================================================");

			// 注册电机
			RegisterMotorsFromDeviceParameters(services);

			Console.WriteLine("==========================================================");
			Console.WriteLine("InfrastructureModule: 电机注册方法调用完成");
			Console.WriteLine("==========================================================");

			// 注册电机控制服务
			services.AddSingleton<IMotorControlService, MotorControlService>();

			return services;
		}

		/// <summary>
		/// 从设备参数配置中注册电机
		/// </summary>
		/// <param name="services">服务集合</param>
		private static void RegisterMotorsFromDeviceParameters(IServiceCollection services)
		{
			Console.WriteLine("开始注册电机 - RegisterMotorsFromDeviceParameters方法被调用");

			// 直接注册电机列表，使用工厂方法获取设备参数并创建电机实例
			services.AddSingleton<IEnumerable<IMotorBase>>(sp =>
			{
				Console.WriteLine("创建电机列表实例");

				var logger = sp.GetRequiredService<ILoggerFactory>().CreateLogger("MotorRegistration");
				var deviceParameterService = sp.GetRequiredService<IDeviceParameterService>();
				var etherCATManager = sp.GetRequiredService<IEtherCATManager>();

				try
				{
					// 同步获取设备参数
					var parametersTask = deviceParameterService.GetParametersAsync();
					parametersTask.Wait(); // 同步等待任务完成
					var parameters = parametersTask.Result;

					if (parameters == null || parameters.Motors == null || parameters.Motors.Count == 0)
					{
						logger.LogWarning("设备参数中没有电机配置");
						return new List<IMotorBase>();
					}

					logger.LogInformation($"从设备参数加载了 {parameters.Motors.Count} 个电机配置");

					// 创建电机实例列表
					var motors = new List<IMotorBase>();

					foreach (var motorConfig in parameters.Motors)
					{
						if (string.IsNullOrEmpty(motorConfig.Id))
						{
							logger.LogWarning("跳过无ID的电机配置");
							continue;
						}

						logger.LogInformation($"创建电机: {motorConfig.Id} ({motorConfig.Name}), 轴号: {motorConfig.AxisId}");

						try
						{
							// 创建电机实例
							var motorLogger = sp.GetRequiredService<ILogger<EtherCATMotorDrive>>();

							var motor = new EtherCATMotorDrive(
								motorConfig.Id,
								motorConfig.Name,
								motorLogger,
								etherCATManager,
								(short)motorConfig.AxisId
							);

							// 设置电机参数
							if (motorConfig.Parameters != null)
							{
								logger.LogInformation($"设置电机 {motorConfig.Id} 的参数: " +
									$"PulsesPerRevolution={motorConfig.Parameters.PulsesPerRevolution}, " +
									$"GearRatio={motorConfig.Parameters.GearRatio}, " +
									$"Unit={motorConfig.Parameters.Unit}");

								motor.SetMotorParameters(motorConfig.Parameters);
							}

							motors.Add(motor);
						}
						catch (Exception ex)
						{
							logger.LogError(ex, $"创建电机 {motorConfig.Id} 实例时出错");
						}
					}

					logger.LogInformation($"成功创建 {motors.Count} 个电机实例");
					return motors;
				}
				catch (Exception ex)
				{
					logger.LogError(ex, "从设备参数加载电机配置时出错");
					return new List<IMotorBase>();
				}
			});

			// 确保不再注册Lazy<Task<List<IMotorBase>>>服务

			Console.WriteLine("电机注册完成 - RegisterMotorsFromDeviceParameters方法结束");
		}
	}
}